package com.pureut.storage.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.bean.BeanUtils;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.production.api.FeignProductionService;
import com.pureut.production.api.domain.LineStock;
import com.pureut.storage.domain.*;
import com.pureut.storage.domain.system.domain.SysDocument;
import com.pureut.storage.dto.*;
import com.pureut.storage.export.ProductionMaterialReturnExport;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.ProductionMaterialReturnDetailService;
import com.pureut.storage.service.ProductionMaterialReturnService;
import com.pureut.storage.service.WarehouseService;
import com.pureut.storage.service.WmsStockInfoService;
import com.pureut.storage.utils.DocumentTypeEnum;
import com.pureut.storage.utils.GenerationMethodEnum;
import com.pureut.storage.vo.*;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.QualityFeginService;
import com.pureut.system.api.RemoteUserService;
import com.pureut.system.api.SystemDocumentFeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.domain.SysUser;
import com.pureut.system.api.vo.MaterialNumberAndBatchNoVo;
import com.pureut.system.api.vo.QualityInspectionDocumentVo;
import com.pureut.system.api.vo.QualitySchemeConfigurationVo;
import com.pureut.system.api.vo.UpdateQualityStatusVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 *
 * Author:C
 * Date:2022/12/30 9:17
 * @DESC
 */
@Service
public class ProductionMaterialReturnServiceImpl extends ServiceImpl<ProductionMaterialReturnMapper, ProductionMaterialReturn> implements ProductionMaterialReturnService {

    @Resource
    ProductionMaterialReturnMapper productionMaterialReturnMapper;

    @Resource
    WarehouseService warehouseService;

    @Resource
    FeignService feignService;

    @Resource
    FeignProductionService feignProductionService;

    @Resource
    SystemDocumentFeignService systemDocumentFeignService;

    @Resource
    ProductionMaterialReturnDetailService productionMaterialReturnDetailService;

    @Resource
    ProductionMaterialReturnDetailMapper productionMaterialReturnDetailMapper;

    @Resource
    WmsStockInfoMapper wmsStockInfoMapper;

    @Resource
    WmsStockInfoService wmsStockInfoService;

    @Resource
    PublicGoodsMapper publicGoodsMapper;

    @Resource
    FeignProductionService FeignProductionService;

    //用户信息
    @Resource
    private RemoteUserService remoteUserService;

    @Resource
    QualityFeginService qualityFeginService;

    @Resource
    OutboundLogMapper outboundLogMapper;

    /**
     * 生产退料列表
     *
     * @param productionMaterialReturnVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<ProductionMaterialReturnDto> getProductionList(ProductionMaterialReturnVo productionMaterialReturnVo) {
        //获取生产退料列表
        List<ProductionMaterialReturnDto> productionList = productionMaterialReturnMapper.getProductionList(productionMaterialReturnVo);
        //单位
        List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取生产退料状态字典值
        List<SysDictData> productionArray = DictUtils.getDictCache("production_material_return_status");
        Map<String, String> productionMap = productionArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取生产退料收发类型
        List<SysDictData> rdArray = DictUtils.getDictCache("production_material_return_rd_type");
        Map<String, String> rdMap = rdArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (ProductionMaterialReturnDto entity : productionList) {
            //状态
            entity.setStatusDict(productionMap.get(entity.getStatus()));
            //单据类型
            entity.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(entity.getDocumentType())));
            //收发类型
            entity.setReceiveTypeDict(rdMap.get(entity.getReceiveType()));
            //生成方式
            entity.setGenerationMethodDict(GenerationMethodEnum.getValue(Integer.parseInt(entity.getGenerationMethod())));
            //单位
            entity.setMaterialUnitDict(unitMap.get(entity.getMaterialUnit()));
        }
        return productionList;
    }

    /**
     * 新增
     *
     * @param productionMaterialReturnVo
     * @return
     */
    @Override
    public boolean addProductionMaterialReturn(ProductionMaterialReturnVo productionMaterialReturnVo) throws Exception {
        List<ProductionVo> productionList = productionMaterialReturnVo.getProductionList();
        List<ProductionMaterialReturn> productionMaterialReturnList = new ArrayList<>();
        if (productionList.size() > 0) {
            for (ProductionVo entity : productionList) {
                ProductionMaterialReturn productionMaterialReturn = new ProductionMaterialReturn();
                String authorityCoding = feignService.getAuthorityCoding("warehouse:warehousing:productionReturn:list");
                if (authorityCoding == null) {
                    throw new GlobalException("该单据未进行配置，无法生成单据编码");
                }
                productionMaterialReturn.setReceiptNo(authorityCoding)
                        .setDeptId(SecurityUtils.getDeptId())
                        .setStatus(1)
                        .setMakingOrderNo(entity.getMakingOrderNo())
                        .setMaterialId(entity.getMaterialId())
                        .setMaterialCode(entity.getMaterialCode())
                        .setMaterialCategory(entity.getMaterialCategory())
                        .setPlannedWeight(entity.getPlannedWeight())
                        .setWarehousingWarehouse(entity.getWarehousingWarehouse())
                        .setWarehousTime(productionMaterialReturnVo.getWarehousTime())
                        .setRemark(productionMaterialReturnVo.getRemark())
                        .setDrawerBy(SecurityUtils.getUsername())
                        .setDrawerTime(new Date())
                        .setReceiveType(productionMaterialReturnVo.getReceiveType())
                        .setDocumentType(DocumentTypeEnum.PRODUCTION_MATERIAL_RETURN.getCode())
                        .setGenerationMethod(GenerationMethodEnum.MANUALLY_GENERATED.getCode());
                productionMaterialReturnList.add(productionMaterialReturn);
            }
            return saveBatch(productionMaterialReturnList);
        } else {
            throw new GlobalException("请至少选择一条数据");
        }
    }

    /**
     * 关结
     *
     * @param productionMaterialReturnVo
     * @return
     */
    @Override
    public boolean close(ProductionMaterialReturnVo productionMaterialReturnVo) {
        ProductionMaterialReturn productionMaterialReturn = getById(productionMaterialReturnVo.getId());
        //已完成、已关结不可重复关结；
        if (productionMaterialReturn.getStatus() != 5 && productionMaterialReturn.getStatus() != 6) {
            //待检验状态的单据关结后，单据状态更新为“已关结”，跳过后续操作，入库的物料显示为在库，关联的品质检验单状态更新为“已撤销”；
            if (productionMaterialReturn.getStatus() == 3) {
                List<ProductionMaterialReturnDetail> productionMaterialReturnDetails = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
                //获取该单据下明细数据物料号码
                List<String> materialNumberList = productionMaterialReturnDetails.stream()
                        .filter(entity -> entity.getStatus() == 2 && entity.getStatus() == 1)
                        .map(ProductionMaterialReturnDetail::getMaterialNumber)
                        .collect(Collectors.toList());

                if (!materialNumberList.isEmpty()) {
                    List<WmsStockInfo> wmsStockInfos = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().in(WmsStockInfo::getWsiMaterialNumber, materialNumberList));
                    for (WmsStockInfo wmsStockInfo : wmsStockInfos) {
                        wmsStockInfo.setWsiMaterialStatus(2);
                    }
                    wmsStockInfoService.updateBatchById(wmsStockInfos);
                }
                //修改对应品质检验单状态为已撤销
                UpdateQualityStatusVo updateQualityStatusVo = new UpdateQualityStatusVo();
                updateQualityStatusVo.setAssociatedNo(productionMaterialReturn.getReceiptNo());
                updateQualityStatusVo.setStatus(8);
                qualityFeginService.updateQualityInspectionDocument(updateQualityStatusVo);
            }
            //待交接状态的单据关结后，单据状态更新为“已关结”，跳过后续操作，入库的物料显示在库
            if (productionMaterialReturn.getStatus() == 4) {
                List<ProductionMaterialReturnDetail> productionMaterialReturnDetails = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
                //获取该单据下明细数据物料号码
                List<String> materialNumberList = productionMaterialReturnDetails.stream()
                        .filter(entity -> entity.getStatus() == 2 && entity.getStatus() == 1)
                        .map(ProductionMaterialReturnDetail::getMaterialNumber)
                        .collect(Collectors.toList());

                if (!materialNumberList.isEmpty()) {
                    List<WmsStockInfo> wmsStockInfos = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().in(WmsStockInfo::getWsiMaterialNumber, materialNumberList));
                    for (WmsStockInfo wmsStockInfo : wmsStockInfos) {
                        wmsStockInfo.setWsiMaterialStatus(2);
                    }
                    wmsStockInfoService.updateBatchById(wmsStockInfos);
                }
            }
            //待入库、部分入库状态的单据关结后，单据状态更新为“已关结”，无影响；
//            if(productionMaterialReturn.getStatus() == 1){
//
//            }
            //入库中的单据关结后，单据状态更新为“已关结”，已扫描过的条码为在库
            if (productionMaterialReturn.getStatus() == 2) {

                List<ProductionMaterialReturnDetail> productionMaterialReturnDetails = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
                //获取该单据下明细数据物料号码
                List<String> materialNumberList = productionMaterialReturnDetails.stream()
                        .filter(entity -> entity.getStatus() == 2 && entity.getStatus() == 1)
                        .map(ProductionMaterialReturnDetail::getMaterialNumber)
                        .collect(Collectors.toList());

                if (!materialNumberList.isEmpty()) {
                    List<WmsStockInfo> wmsStockInfos = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().in(WmsStockInfo::getWsiMaterialNumber, materialNumberList));
                    for (WmsStockInfo wmsStockInfo : wmsStockInfos) {
                        wmsStockInfo.setWsiMaterialStatus(2);
                    }
                    wmsStockInfoService.updateBatchById(wmsStockInfos);
                }
            }

            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = simpleDateFormat.format(date);

            productionMaterialReturn.setStatus(6)
                    .setCloseReason(productionMaterialReturnVo.getCloseReason())
                    .setClosingBy(SecurityUtils.getUsername());
            if (productionMaterialReturn.getClosingTime() == null) {
                productionMaterialReturn.setClosingTime(format);
            } else {
                productionMaterialReturn.setClosingTime(productionMaterialReturn.getClosingTime() + "," + format);
            }
        } else {
            throw new GlobalException("已完成、已关结不可重复关结");
        }
        return updateById(productionMaterialReturn);

    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public ProductionMaterialReturnDto getView(Long id) {

        ProductionMaterialReturnDto productionById = productionMaterialReturnMapper.getProductionById(id);

        //单据类型
        productionById.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(productionById.getDocumentType())));

        //收发类型
        List<SysDictData> rdArray = DictUtils.getDictCache("production_material_return_rd_type");
        Map<String, String> rdMap = rdArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //单位
        List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        productionById.setReceiveTypeDict(rdMap.get(String.valueOf(productionById.getReceiveType())));

        List<ProductionViewVo> productionViewVos = new ArrayList<>();
        ProductionViewVo productionViewVo = new ProductionViewVo();
        //制令单号
        productionViewVo.setMakingOrderNo(productionById.getMakingOrderNo());
        //计划数量
        productionViewVo.setPlannedWeight(productionById.getPlannedWeight());
        //仓库
        productionViewVo.setWarehousingWarehouse(Long.parseLong(productionById.getWarehousingWarehouse()));
        productionViewVo.setWarehousingWarehouseDict(productionById.getWarehouseName());

        //物料信息
        productionViewVo.setMaterialName(productionById.getMaterialName());
        productionViewVo.setMaterialCode(productionById.getMaterialCode());
        productionViewVo.setMaterialSpec(productionById.getMaterialSpec());
        productionViewVo.setMaterialUnit(productionById.getMaterialUnit());
        productionViewVo.setMaterialUnitDict(unitMap.get(productionById.getMaterialUnit()));

        productionViewVos.add(productionViewVo);
        productionById.setProductionList(productionViewVos);
        return productionById;
    }

    /**
     * 修改
     *
     * @param productionMaterialReturnVo
     * @return
     */
    @Override
    public boolean updateProductionMaterialReturn(ProductionMaterialReturnVo productionMaterialReturnVo) {
        ProductionMaterialReturn productionMaterialReturn = getById(productionMaterialReturnVo.getId());
        if (productionMaterialReturn.getStatus() == 1) {
//            BeanUtils.copyProperties(productionMaterialReturnVo, productionMaterialReturn);
            productionMaterialReturn.setReceiveType(productionMaterialReturnVo.getReceiveType());
            productionMaterialReturn.setWarehousTime(productionMaterialReturnVo.getWarehousTime());
            productionMaterialReturn.setRemark(productionMaterialReturnVo.getRemark());
            List<ProductionVo> productionList = productionMaterialReturnVo.getProductionList();
            for (ProductionVo entity : productionList) {
                productionMaterialReturn.setPlannedWeight(entity.getPlannedWeight())
                        .setWarehousingWarehouse(entity.getWarehousingWarehouse())
                        .setMakingOrderNo(entity.getMakingOrderNo())
                        .setMaterialCode(entity.getMaterialCode())
                        .setMaterialId(entity.getMaterialId());
            }
            return updateById(productionMaterialReturn);
        } else {
            throw new GlobalException("只能修改待入库的数据");
        }
    }

    /**
     * 删除
     *
     * @param idStr
     * @return
     */
    @Override
    public boolean deleteProductionMaterialReturn(String idStr) {
        List<String> idList = Arrays.asList(idStr.split(","));
        if (idList.size() == 0) {
            throw new GlobalException("至少勾选一条数据");
        }
        List<ProductionMaterialReturn> productionMaterialReturnList = new ArrayList<>();
        List<ProductionMaterialReturn> productionMaterialReturns = productionMaterialReturnMapper.selectList(new QueryWrapper<ProductionMaterialReturn>().lambda().in(ProductionMaterialReturn::getId, idList));
        for (ProductionMaterialReturn entity : productionMaterialReturns) {
            if (entity.getStatus() == 1) {
                productionMaterialReturnList.add(entity);
            } else {
                throw new GlobalException("只能删除待入库的单据");
            }
        }
        List<ProductionMaterialReturn> deleteList = new ArrayList<>();
        for (ProductionMaterialReturn entity : productionMaterialReturnList) {
            if (entity.getGenerationMethod() == 2) {
                deleteList.add(entity);
            } else {
                throw new GlobalException("自动生成的单据不能删除");
            }
        }
        return removeByIds(deleteList);
    }

    /**
     * 导出
     *
     * @param productionMaterialReturnVo
     * @return
     */
    @Override
    public List<ProductionMaterialReturnExport> getInfoExport(ProductionMaterialReturnVo productionMaterialReturnVo) {
        List<ProductionMaterialReturnExportDto> productionMaterialReturnList = null;
        if (productionMaterialReturnVo.getIdStr() == null) {
            productionMaterialReturnList = productionMaterialReturnMapper.getProductionListOut(productionMaterialReturnVo);
        } else {
            List<String> idList = Arrays.asList(productionMaterialReturnVo.getIdStr().split(","));
            productionMaterialReturnList = productionMaterialReturnMapper.getDataByIdStr(idList);
        }

        //获取生产退料收发类型
        List<SysDictData> rdArray = DictUtils.getDictCache("production_material_return_rd_type");
        Map<String, String> rdMap = rdArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<ProductionMaterialReturnExport> productionMaterialReturnExportList = new ArrayList<>();
        for (ProductionMaterialReturnExportDto entity : productionMaterialReturnList) {
            ProductionMaterialReturnExport productionMaterialReturnExport = new ProductionMaterialReturnExport();

            BeanUtils.copyProperties(entity, productionMaterialReturnExport);
            //收发类型
            if (!"0".equals(entity.getReceiveType())) {
                productionMaterialReturnExport.setReceiveType(rdMap.get(String.valueOf(entity.getReceiveType())));
            } else {
                productionMaterialReturnExport.setReceiveType("");
            }
            productionMaterialReturnExportList.add(productionMaterialReturnExport);
        }
        return productionMaterialReturnExportList;
    }

    /**
     * 生产退料pda入库
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestDbDto productionReturnPda(PickingRestDbVo pickingRestDbVo) throws Exception {
        PickingRestDbDto pickingRestDbDto = new PickingRestDbDto();
        ProductionMaterialReturn productionMaterialReturn = getById(pickingRestDbVo.getId());
        if (productionMaterialReturn.getStatus() == 1 || productionMaterialReturn.getStatus() == 2) {
            //扫码入库
            if ("1".equals(pickingRestDbVo.getType())) {
                //如果是第一步，需要查询库位信息
                if (pickingRestDbVo.getExecutionOrder() == 1) {
                    WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(pickingRestDbVo.getInputValue());
                    if (warehouseCode.getCombinationName() == null) {
                        pickingRestDbDto.setMessage("没有该仓库信息，请核实!");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }
                    pickingRestDbDto.setWarehouseMessage(warehouseCode.getCombinationName());
                    pickingRestDbDto.setCkId(warehouseCode.getCkId());
                    pickingRestDbDto.setKqId(warehouseCode.getKqId());
                    pickingRestDbDto.setKwId(warehouseCode.getKwId());
                    pickingRestDbDto.setMessage("操作成功");
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
                //如果是第二步，需要根据物料号码保存明细信息
                if (pickingRestDbVo.getExecutionOrder() == 2) {
                    ProductionMaterialReturnVo productionMaterialReturnVo = new ProductionMaterialReturnVo();
                    //获取生产退料列表
                    List<ProductionMaterialReturnDto> productionList = productionMaterialReturnMapper.getProductionList(productionMaterialReturnVo);

                    //查询线边库存数据
                    String materialNumber = pickingRestDbVo.getInputValue();
                    AjaxResult lineStockData = FeignProductionService.getLineStockData(materialNumber);
                    LineStockDto data = JSON.parseObject(JSON.toJSONString(lineStockData.get("data")), LineStockDto.class);
                    if (data.getMaterialCode() == null) {
                        pickingRestDbDto.setCode("500");
                        pickingRestDbDto.setMessage("没有查询到对应物料，请核实后输入!");
                        return pickingRestDbDto;
                    }

                    Long menuId = feignService.getIdByMenuName("生产退料");
                    AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
                    SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);

                    //如果配置了送检,则校验是否配了检验方案
                    if (sysDocument.getDocInspectionMark() == 1) {

                        List<SysDocumentCheckDto> documentCheckDtoList = sysDocument.getDocumentCheckDtoList();
                        if (documentCheckDtoList == null) {
                            throw new GlobalException("请先在单据配置中配置送检方案");
                        }

                        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturn.getMaterialCode()));

                        QualitySchemeConfigurationVo qualitySchemeConfigurationVo = new QualitySchemeConfigurationVo();
                        qualitySchemeConfigurationVo.setCategory(publicGoods.getMaterialCategory());
                        qualitySchemeConfigurationVo.setItemRank(documentCheckDtoList.get(0).getCheckSubmit());
                        qualitySchemeConfigurationVo.setMaterialCategory(publicGoods.getMaterialType());
                        qualitySchemeConfigurationVo.setMaterialCode(productionMaterialReturn.getMaterialCode());
                        boolean check = qualityFeginService.check(qualitySchemeConfigurationVo);

                        if (!check) {
                            throw new GlobalException("该物料不存在对应的检验方案");

                        }
                    }

                    ProductionMaterialReturnDetail productionMaterialReturnDetail = new ProductionMaterialReturnDetail();
                    //根据扫描的物料编码和入库列表数据进行比对
                    for (ProductionMaterialReturnDto entity : productionList) {
                        //如果对应的编码相等，就将该明细存入
                        if (entity.getMaterialCode().equals(data.getMaterialCode())) {
                            //是否配置了送检
                            if (sysDocument.getDocInspectionMark() == 1) {
                                //修改明细状态为待送检
                                productionMaterialReturnDetail.setStatus(1);
                            } else {
                                //修改明细状态为待交接
                                productionMaterialReturnDetail.setStatus(2);
                            }
                            productionMaterialReturnDetail.setMaterialCode(data.getMaterialCode());
                            productionMaterialReturnDetail.setWareAlCode(data.getWareAlCode());
                            productionMaterialReturnDetail.setLineCode(data.getLineCode());
                            productionMaterialReturnDetail.setMaterialNumber(pickingRestDbVo.getInputValue());
                            productionMaterialReturnDetail.setGrossWeight(data.getGrossWeight());
                            productionMaterialReturnDetail.setNetWeight(data.getNetWeight());
                            productionMaterialReturnDetail.setReceiptQuantity(1);
                            productionMaterialReturnDetail.setBatchNo(data.getStockBatch());
                            productionMaterialReturnDetail.setWarehouseMessage(pickingRestDbVo.getCombinationName());
                            productionMaterialReturnDetail.setWarehouseInBy(SecurityUtils.getUsername());
                            productionMaterialReturnDetail.setWarehouseInTime(new Date());
                            productionMaterialReturnDetail.setProductionMaterialReturnId(entity.getId());
                            productionMaterialReturnDetailService.save(productionMaterialReturnDetail);

                            //查询该物料是否入库过
                            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, pickingRestDbVo.getInputValue()));

                            if (wmsStockInfo != null) {
                                pickingRestDbDto.setMessage("该数据已经入库");
                                pickingRestDbDto.setCode("500");
                                return pickingRestDbDto;
                            }
                            PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturnDetail.getMaterialCode()));
                            OutboundLog outboundLog = outboundLogMapper.selectOne(new QueryWrapper<OutboundLog>().lambda().eq(OutboundLog::getWsiMaterialNumber, pickingRestDbVo.getInputValue()));

                            //向仓库表中添加对应的数据
                            WmsStockInfo wmsStockInfo1 = new WmsStockInfo();
                            wmsStockInfo1.setWsiMaterialNumber(productionMaterialReturnDetail.getMaterialNumber())
                                    .setWsiWarehourse(outboundLog.getWsiWarehourse())
                                    .setWsiReservoirArea(outboundLog.getWsiReservoirArea())
                                    .setWsiStorageLoaction(outboundLog.getWsiStorageLoaction())
                                    .setWsiMaterialGrade(outboundLog.getWsiMaterialGrade())
                                    .setWsiSupplierCode(outboundLog.getWsiSupplierCode())
                                    .setWsiDocNum(productionMaterialReturn.getReceiptNo())
                                    .setWsiConnectNum(productionMaterialReturn.getMakingOrderNo())
                                    .setWsiProducedDate(outboundLog.getWsiProducedDate())
                                    .setWsiMaterialCode(productionMaterialReturnDetail.getMaterialCode())
                                    .setWsiCategory(String.valueOf(publicGoods.getMaterialCategory()))
                                    .setWsiMaterialType(publicGoods.getMaterialType())
                                    .setWsiMaterialNum(1)
                                    .setWsiMaterialStatus(2)
                                    .setWsiMaterialBatch(productionMaterialReturnDetail.getBatchNo())
                                    .setWsiGorssWeight(productionMaterialReturnDetail.getGrossWeight())
                                    .setWsiNetWeight(productionMaterialReturnDetail.getNetWeight())
                                    .setWsiReveiveTime(new Date())
                                    .setCreateUser(SecurityUtils.getUsername())
                                    .setCreateTime(new Date());
                            wmsStockInfoService.save(wmsStockInfo1);
                            //删除对应线边仓数据
                            feignProductionService.deleteLineStock(materialNumber);
                            break;
                        }
                    }
                    if (productionMaterialReturnDetail.getMaterialCode() == null) {
                        pickingRestDbDto.setMessage("没有匹配的物料，请核实!");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }

                    PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturnDetail.getMaterialCode()));
                    //获取单位字典值
                    List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
                    Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

                    //判断单位
                    if ("2".equals(publicGoods.getMaterialUnit())) {
                        //如果单位是千克
                        if (productionMaterialReturn.getActualQuantity() == null || "".equals(productionMaterialReturn.getActualQuantity())) {
                            productionMaterialReturn.setActualQuantity(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            //修改采购入库信息入库重量
                            productionMaterialReturn.setWarehousingWeight(productionMaterialReturnDetail.getNetWeight());
                        } else {
                            BigDecimal bigDecimal = new BigDecimal(productionMaterialReturn.getActualQuantity());
                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            String s = bigDecimal.add(bigDecimal1).toString();
                            productionMaterialReturn.setActualQuantity(s);
                            //修改采购入库信息入库重量
                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            String s1 = bigDecimal2.add(bigDecimal3).toString();
                            productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                        }
                    } else if ("3".equals(publicGoods.getMaterialUnit())) {
                        //如果单位是吨，若单位为吨，则实际量=入库重量（kg）/1000
                        if (productionMaterialReturn.getActualQuantity() == null || "".equals(productionMaterialReturn.getActualQuantity())) {
                            BigDecimal bigDecimal = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            BigDecimal divide = bigDecimal.divide(new BigDecimal("1000"));
                            productionMaterialReturn.setActualQuantity(divide.toString());
                            //修改采购入库信息入库重量
                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            String s1 = bigDecimal2.add(bigDecimal3).toString();
                            productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                        } else {
                            BigDecimal bigDecimal = new BigDecimal(productionMaterialReturn.getActualQuantity());
                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            BigDecimal divide = bigDecimal1.divide(new BigDecimal("1000"));
                            String s = bigDecimal.add(divide).toString();
                            productionMaterialReturn.setActualQuantity(s);
                            //修改采购入库信息入库重量
                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            String s1 = bigDecimal2.add(bigDecimal3).toString();
                            productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                        }
                    } else {
                        if (productionMaterialReturn.getActualQuantity() == null || "".equals(productionMaterialReturn.getActualQuantity())) {
                            productionMaterialReturn.setActualQuantity(String.valueOf(productionMaterialReturnDetail.getReceiptQuantity()));
                            //修改采购入库信息入库重量
                            productionMaterialReturn.setWarehousingWeight(productionMaterialReturnDetail.getNetWeight());
                        } else {
                            BigDecimal bigDecimal = new BigDecimal(productionMaterialReturn.getActualQuantity());
                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getReceiptQuantity()));
                            String s = bigDecimal.add(bigDecimal1).toString();
                            productionMaterialReturn.setActualQuantity(s);
                            //修改采购入库信息入库重量
                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                            String s1 = bigDecimal2.add(bigDecimal3).toString();
                            productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                        }
                    }
                    int warehousingNum = productionMaterialReturn.getWarehousingNum();
                    if (warehousingNum == 0) {
                        productionMaterialReturn.setWarehousingNum(1);
                    } else {
                        productionMaterialReturn.setWarehousingNum(warehousingNum + 1);
                    }


                    pickingRestDbDto.setQuantityIdentification(productionMaterialReturn.getPlannedWeight() + "/" + productionMaterialReturn.getActualQuantity() + unitMap.get(publicGoods.getMaterialUnit()));
                    pickingRestDbDto.setMessage("物料号码:" + productionMaterialReturnDetail.getMaterialNumber() + "," + "净重:" + productionMaterialReturnDetail.getNetWeight() + unitMap.get(publicGoods.getMaterialUnit()) + "," + "数量:" + productionMaterialReturnDetail.getReceiptQuantity() + "," + "录入成功");
                    pickingRestDbDto.setUnit(publicGoods.getMaterialUnit());
                    pickingRestDbDto.setUnitDict(unitMap.get(publicGoods.getMaterialUnit()));
                    pickingRestDbDto.setWarehouseNumber(String.valueOf(productionMaterialReturn.getWarehousingNum()));


                    double aDouble = Double.parseDouble(productionMaterialReturn.getActualQuantity());
                    double plannedWeight = productionMaterialReturn.getPlannedWeight();

                    //判断是否配置了超收
                    if (sysDocument.getDocExcessMark() == 2 && publicGoods.getMaterialClosed() == 2) {
                        if (Double.doubleToLongBits(aDouble) >= Double.doubleToLongBits(plannedWeight)) {
                            //如果配置了送检
                            if (sysDocument.getDocInspectionMark() == 1) {
                                productionMaterialReturn.setStatus(3);
                                updateById(productionMaterialReturn);
                                // 生成品质检验单
                                if (sysDocument.getDocCode() == null) {
                                    throw new GlobalException("未进行单据配置");
                                }
                                List<SysDocumentCheckDto> documentCheckDtoList = sysDocument.getDocumentCheckDtoList();
                                if (documentCheckDtoList.size() < 1) {
                                    throw new GlobalException("未进行检验单生成配置");
                                }
                                //通过物料编码获取物料类别
                                //PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, pickingSaleDetail.getItemCode()));
                                //获取明细列表
                                List<ProductionMaterialReturnDetail> salesReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
                                StringBuilder stringBuilder = new StringBuilder();
                                for (ProductionMaterialReturnDetail entity : salesReturnDetailList) {
                                    stringBuilder.append(entity.getBatchNo()).append(",");
                                }
                                StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);


                                for (SysDocumentCheckDto checkDto : documentCheckDtoList) {
                                    if (checkDto.getCheckType() == publicGoods.getMaterialCategory()) {
                                        QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                                        qualityInspectionDocumentVo.setItemRank(checkDto.getCheckSubmit());
                                        qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                                        qualityInspectionDocumentVo.setMaterialCategory(Long.parseLong(String.valueOf(publicGoods.getMaterialType())));
                                        qualityInspectionDocumentVo.setMaterialCode(productionMaterialReturn.getMaterialCode());
                                        qualityInspectionDocumentVo.setBatchNo(stringBuilder1.toString());
                                        qualityInspectionDocumentVo.setAssociatedNo(productionMaterialReturn.getReceiptNo());
//                                        qualityInspectionDocumentVo.setDifferentString(customerManagement.getCustomerNum());
                                        qualityInspectionDocumentVo.setModeType(13);

                                        List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNo = new ArrayList<>();
                                        for (ProductionMaterialReturnDetail entity : salesReturnDetailList) {
                                            MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                                            materialNumberAndBatchNoVo.setBatchNo(entity.getBatchNo());
                                            materialNumberAndBatchNoVo.setMaterialNumber(entity.getMaterialNumber());
                                            materialNumberAndBatchNo.add(materialNumberAndBatchNoVo);
                                        }
                                        qualityInspectionDocumentVo.setMaterialNumberAndBatchNo(materialNumberAndBatchNo);

//                                        AjaxResult add = qualityFeginService.add(qualityInspectionDocumentVo);
                                        boolean b = qualityFeginService.addWares(qualityInspectionDocumentVo);
//                                        String code = add.get("code").toString();
                                        if (!b) {
                                            pickingRestDbDto.setMessage("生成品质检验单失败");
                                            pickingRestDbDto.setCode("500");
                                            return pickingRestDbDto;
                                        }
                                    }
                                }
                                pickingRestDbDto.setCode("200");
                                return pickingRestDbDto;
                            }
                            //如果配置了交接
                            if (sysDocument.getDocHandoverMark() == 1) {
                                productionMaterialReturn.setStatus(4);
                                updateById(productionMaterialReturn);
                                pickingRestDbDto.setCode("200");
                                return pickingRestDbDto;
                            } else {
                                productionMaterialReturn.setStatus(5);
                                updateById(productionMaterialReturn);
                                pickingRestDbDto.setCode("200");
                                return pickingRestDbDto;
                            }
                        }
                    }
                    productionMaterialReturn.setStatus(2);
                    pickingRestDbDto.setCode("200");
                    updateById(productionMaterialReturn);
                    return pickingRestDbDto;
                }
            }
            //条码撤销
            if ("2".equals(pickingRestDbVo.getType())) {
//                //如果是第一步，需要查询库位信息
//                if (pickingRestDbVo.getExecutionOrder() == 1) {
//                    WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(pickingRestDbVo.getInputValue());
//                    if (warehouseCode.getCombinationName() == null) {
//                        pickingRestDbDto.setMessage("没有该仓库信息，请核实!");
//                        pickingRestDbDto.setCode("500");
//                        return pickingRestDbDto;
//                    }
//                    pickingRestDbDto.setWarehouseMessage(warehouseCode.getCombinationName());
//                    pickingRestDbDto.setCkId(warehouseCode.getCkId());
//                    pickingRestDbDto.setKqId(warehouseCode.getKqId());
//                    pickingRestDbDto.setKwId(warehouseCode.getKwId());
//                    pickingRestDbDto.setMessage("操作成功");
//                    pickingRestDbDto.setCode("200");
//                    return pickingRestDbDto;
//                }
                //如果是第二步，需要根据物料号码查询明细信息
//                if (pickingRestDbVo.getExecutionOrder() == 2) {
                //查询该条码是否扫描过
                WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, pickingRestDbVo.getInputValue()));
                if (wmsStockInfo == null) {
                    pickingRestDbDto.setCode("500");
                    pickingRestDbDto.setMessage("撤销失败，请核实后再录入");
                    return pickingRestDbDto;
                }
                wmsStockInfoMapper.deleteById(wmsStockInfo);

                //同时删除生产退料明细状态
                ProductionMaterialReturnDetail productionMaterialReturnDetail = productionMaterialReturnDetailMapper.selectOne(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getMaterialNumber, pickingRestDbVo.getInputValue()));
                //保存至线边仓
                LineStock lineStock = new LineStock();
                lineStock.setMaterialNumber(productionMaterialReturnDetail.getMaterialNumber());
                lineStock.setMaterialGrade(1);
                lineStock.setMaterialCode(productionMaterialReturnDetail.getMaterialCode());
                lineStock.setStockBatch(productionMaterialReturnDetail.getBatchNo());
                lineStock.setGrossWeight(productionMaterialReturnDetail.getGrossWeight());
                lineStock.setNetWeight(productionMaterialReturnDetail.getNetWeight());
                lineStock.setStockAlCode(productionMaterialReturn.getMakingOrderNo());
                lineStock.setWareAlCode(productionMaterialReturnDetail.getWareAlCode());
                lineStock.setLineCode(productionMaterialReturnDetail.getLineCode());
                lineStock.setIntoTheTime(new Date());
                lineStock.setFreezeMark(2);
                feignProductionService.addLineStock(lineStock);
                PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturn.getMaterialCode()));
                //获取单位字典值
                List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
                Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
                //设置返回信息
                pickingRestDbDto.setMessage("物料号码:" + productionMaterialReturnDetail.getMaterialNumber() + "," + "净重:" + productionMaterialReturnDetail.getNetWeight() + unitMap.get(publicGoods.getMaterialUnit()) + "," + "数量:" + productionMaterialReturnDetail.getReceiptQuantity() + "," + "撤销成功");
                pickingRestDbDto.setQuantityIdentification(productionMaterialReturn.getPlannedWeight() + "/" + productionMaterialReturn.getActualQuantity() + unitMap.get(publicGoods.getMaterialUnit()));
                pickingRestDbDto.setUnit(publicGoods.getMaterialUnit());
                pickingRestDbDto.setUnitDict(unitMap.get(publicGoods.getMaterialUnit()));
                pickingRestDbDto.setWarehouseNumber(String.valueOf(productionMaterialReturn.getWarehousingNum()));

                List<ProductionMaterialReturnDetail> list = productionMaterialReturnDetailService.list();
                //判断条数修改采购入库状态
                if (list.size() == 0) {
                    productionMaterialReturn.setStatus(1);
                    productionMaterialReturn.setWarehousingNum(0);
                    productionMaterialReturn.setWarehousingWeight(0);
                    productionMaterialReturn.setActualQuantity("0");
                } else {
//                        productionMaterialReturn.setWarehousingNum(productionMaterialReturn.getWarehousingNum() - 1);
                    //判断单位
                    BigDecimal bigDecimal = new BigDecimal(productionMaterialReturn.getActualQuantity());
                    BigDecimal bigDecimal1;
                    if ("2".equals(publicGoods.getMaterialUnit())) {
                        //如果是千克
                        bigDecimal1 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                        String s = bigDecimal.subtract(bigDecimal1).toString();
                        productionMaterialReturn.setActualQuantity(s);
                        //修改采购入库信息入库重量
                        BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                        BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                        String s1 = bigDecimal2.subtract(bigDecimal3).toString();
                        productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                        //入库数量
                    } else if ("3".equals(publicGoods.getMaterialUnit())) {
                        //如果单位是吨，若单位为吨，则实际量=入库重量（kg）/1000
                        BigDecimal bigDecimalNetWeight = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                        BigDecimal divide = bigDecimalNetWeight.divide(new BigDecimal("1000"));
                        String s = bigDecimal.subtract(divide).toString();
                        productionMaterialReturn.setActualQuantity(s);

                        //修改采购入库信息入库重量
                        BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                        BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                        String s1 = bigDecimal2.subtract(bigDecimal3).toString();
                        productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                    } else {
                        //不是千克
                        bigDecimal1 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getReceiptQuantity()));
                        String s = bigDecimal.subtract(bigDecimal1).toString();
                        productionMaterialReturn.setActualQuantity(s);
                        //修改采购入库信息入库重量
                        BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(productionMaterialReturn.getWarehousingWeight()));
                        BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight()));
                        String s1 = bigDecimal2.subtract(bigDecimal3).toString();
                        productionMaterialReturn.setWarehousingWeight(Double.parseDouble(s1));
                    }
                    //入库数量
                    productionMaterialReturn.setWarehousingNum(productionMaterialReturn.getWarehousingNum() - 1);
                }
                updateById(productionMaterialReturn);
                productionMaterialReturnDetailMapper.deleteById(productionMaterialReturnDetail);

                pickingRestDbDto.setCode("200");
                return pickingRestDbDto;
//                }
            }
        } else {
            pickingRestDbDto.setCode("500");
            pickingRestDbDto.setMessage("只能操作待入库和入库中得数据");
            return pickingRestDbDto;
        }
        pickingRestDbDto.setMessage("步骤不正确,请核实!");
        pickingRestDbDto.setCode("500");
        return pickingRestDbDto;
    }

    /**
     * 生产退料拣货撤销
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pickingCancellation(PickingRestDbVo pickingRestDbVo) {
        //获取生产退料数据
        ProductionMaterialReturn productionMaterialReturn = getById(pickingRestDbVo.getId());
        //根据生产退料id获取明细数据
        List<ProductionMaterialReturnDetail> productionMaterialReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, pickingRestDbVo.getId()));
        if (productionMaterialReturnDetailList.size() < 1) {
            throw new GlobalException("不存在入库明细，请核实!");
        }
        //根据批次号查询仓库信息
        List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, productionMaterialReturnDetailList.get(0).getBatchNo()));
        //删除仓储数据
        wmsStockInfoMapper.deleteBatchIds(wmsStockInfoList);
        //对应的物料号码回到线边库存中
        for (ProductionMaterialReturnDetail entity : productionMaterialReturnDetailList) {
            //保存至线边仓
            LineStock lineStock = new LineStock();
            lineStock.setMaterialNumber(entity.getMaterialNumber());
            lineStock.setMaterialGrade(1);
            lineStock.setMaterialCode(entity.getMaterialCode());
            lineStock.setStockBatch(entity.getBatchNo());
            lineStock.setGrossWeight(entity.getGrossWeight());
            lineStock.setNetWeight(entity.getNetWeight());
            lineStock.setStockAlCode(productionMaterialReturn.getMakingOrderNo());
            lineStock.setWareAlCode(entity.getWareAlCode());
            lineStock.setLineCode(entity.getLineCode());
            lineStock.setIntoTheTime(new Date());
            lineStock.setFreezeMark(2);
            feignProductionService.addLineStock(lineStock);
        }
        //删除明细数据
        productionMaterialReturnDetailMapper.deleteBatchIds(productionMaterialReturnDetailList);
        //修改销售退货状态
        productionMaterialReturn.setStatus(1);
        productionMaterialReturn.setWarehousingNum(0);
        productionMaterialReturn.setWarehousingWeight(0);
        productionMaterialReturn.setActualQuantity("0");
        //删除关联的检验单
        String relevanceDoc = productionMaterialReturn.getReceiptNo();
        qualityFeginService.removeDoc(relevanceDoc);
        return updateById(productionMaterialReturn);
    }

    /**
     * 生产退料拣货完成
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pickingCompleted(PickingRestDbVo pickingRestDbVo) throws Exception {
        ProductionMaterialReturn productionMaterialReturn = getById(pickingRestDbVo.getId());
        //需求量
        double aDouble = Double.parseDouble(productionMaterialReturn.getActualQuantity());
        //计划量
        double planWeight = productionMaterialReturn.getPlannedWeight();

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturn.getMaterialCode()));

        Long menuId = feignService.getIdByMenuName("生产退料");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        //配置了超收
//        if (sysDocument.getDocExcessMark() == 1) {
//            if (Double.doubleToLongBits(aDouble) >= Double.doubleToLongBits(planWeight)) {
        //如果配置了送检
        if (sysDocument.getDocInspectionMark() == 1) {
            productionMaterialReturn.setStatus(3);
            // 生成品质检验单
            if (sysDocument.getDocCode() == null) {
                throw new GlobalException("未进行单据配置");
            }
            List<SysDocumentCheckDto> documentCheckDtoList = sysDocument.getDocumentCheckDtoList();
            if (documentCheckDtoList.size() < 1) {
                throw new GlobalException("未进行检验单生成配置");
            }
            //通过物料编码获取物料类别
            //PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, pickingSaleDetail.getItemCode()));
            //获取明细列表
            List<ProductionMaterialReturnDetail> salesReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
            StringBuilder stringBuilder = new StringBuilder();
            for (ProductionMaterialReturnDetail entity : salesReturnDetailList) {
                stringBuilder.append(entity.getBatchNo()).append(",");
            }
            StringBuilder stringBuilderBatch = stringBuilder.deleteCharAt(stringBuilder.length() - 1);

            for (SysDocumentCheckDto checkDto : documentCheckDtoList) {
                if (checkDto.getCheckType() == publicGoods.getMaterialCategory()) {
                    QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                    qualityInspectionDocumentVo.setItemRank(checkDto.getCheckSubmit());
                    qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                    qualityInspectionDocumentVo.setMaterialCategory(Long.parseLong(String.valueOf(publicGoods.getMaterialType())));
                    qualityInspectionDocumentVo.setMaterialCode(productionMaterialReturn.getMaterialCode());
                    qualityInspectionDocumentVo.setBatchNo(stringBuilderBatch.toString());
                    qualityInspectionDocumentVo.setAssociatedNo(productionMaterialReturn.getReceiptNo());
//                    qualityInspectionDocumentVo.setDifferentString(customerManagement.getCustomerNum());
                    qualityInspectionDocumentVo.setModeType(13);

                    List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNo = new ArrayList<>();
                    for (ProductionMaterialReturnDetail entity : salesReturnDetailList) {
                        MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                        materialNumberAndBatchNoVo.setBatchNo(entity.getBatchNo());
                        materialNumberAndBatchNoVo.setMaterialNumber(entity.getMaterialNumber());
                        materialNumberAndBatchNo.add(materialNumberAndBatchNoVo);
                    }
                    qualityInspectionDocumentVo.setMaterialNumberAndBatchNo(materialNumberAndBatchNo);

                    AjaxResult add = qualityFeginService.add(qualityInspectionDocumentVo);
                    String code = add.get("code").toString();
                    if ("500".equals(code)) {
                        throw new GlobalException("生成品质检验单失败");
                    }
                }
            }
            return updateById(productionMaterialReturn);
        }
        //如果配置了交接
        if (sysDocument.getDocHandoverMark() == 1) {
            productionMaterialReturn.setStatus(4);
            return updateById(productionMaterialReturn);
        }
//            }
//        }
        productionMaterialReturn.setStatus(5);
        return updateById(productionMaterialReturn);
    }

    /**
     * 生产退料交接
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestHandoverDto handover(PickingRestDbVo pickingRestDbVo) {
        String username = SecurityUtils.getUsername();
        PickingRestHandoverDto pickingRestHandoverDto = new PickingRestHandoverDto();
        ProductionMaterialReturn productionMaterialReturn = getById(pickingRestDbVo.getId());

        if (productionMaterialReturn.getStatus() != 4) {
            pickingRestHandoverDto.setResultCode("500");
            pickingRestHandoverDto.setMessage("只能操作待交接的单据");
            return pickingRestHandoverDto;
        }
        //获取单位字典值
        List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取单据配置信息
        Long menuId = feignService.getIdByMenuName("生产退料");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        //第一步根据工号查询交接人
        if (pickingRestDbVo.getExecutionOrder() == 1) {
            //根据工号查询交接人
            String userName = pickingRestDbVo.getInputValue();
            AjaxResult byUserName = remoteUserService.getByUserName(userName);
            SysUser userInfo = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);
            //校验员工编号
            if (userInfo.getUserName() == null) {
                pickingRestHandoverDto.setResultCode("500");
                pickingRestHandoverDto.setMessage("交接人输入有误,请核对后输入");
                return pickingRestHandoverDto;
            }
//            //返回交接人
//            pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());
//            pickingRestHandoverDto.setDocHandoverMethod(sysDocument.getDocHandoverMethod());
//            pickingRestHandoverDto.setResultCode("200");
//            pickingRestHandoverDto.setMessage("操作成功");
//            return pickingRestHandoverDto;
//        }
            pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());

            //第二步
//        if (pickingRestDbVo.getExecutionOrder() == 2) {
            PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturn.getMaterialCode()));

//            //判断单据状态是否为待交接
//            if (productionMaterialReturn.getStatus() == 4) {
            //如果是整单
            if (sysDocument.getDocHandoverMethod() == 3) {
                BigDecimal bigDecimalNetWeight = new BigDecimal(0);
                //根据id获取明细信息
                List<ProductionMaterialReturnDetail> productionMaterialReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
                for (ProductionMaterialReturnDetail entity : productionMaterialReturnDetailList) {
                    entity.setStatus(3);
                    bigDecimalNetWeight = bigDecimalNetWeight.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
                }
                productionMaterialReturnDetailService.updateBatchById(productionMaterialReturnDetailList);
                //修改销售退货状态为已经完成
                productionMaterialReturn.setStatus(5);
                productionMaterialReturn.setHandoverWeight(Double.parseDouble(bigDecimalNetWeight.toString()));
                productionMaterialReturn.setHandoverNum(productionMaterialReturnDetailList.size());
                String closingBy = productionMaterialReturn.getClosingBy();
                if (closingBy == null) {
                    productionMaterialReturn.setClosingBy(userName);
                } else {
                    productionMaterialReturn.setClosingBy(closingBy + "," + userName);
                }
                String closingTime = productionMaterialReturn.getClosingTime();
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String format = simpleDateFormat.format(date);
                if (closingTime == null) {
                    productionMaterialReturn.setClosingTime(closingTime);
                } else {
                    productionMaterialReturn.setClosingTime(closingTime + "," + format);
                }
                updateById(productionMaterialReturn);

                //设置出参数据
                pickingRestHandoverDto.setQuantityIdentification(productionMaterialReturn.getPlannedWeight() + "/" + bigDecimalNetWeight + unitMap.get(publicGoods.getMaterialUnit()));
                pickingRestHandoverDto.setOutHandoverActual(productionMaterialReturnDetailList.size() + "/" + productionMaterialReturnDetailList.size());
                pickingRestHandoverDto.setMessage("单据号:" + productionMaterialReturn.getReceiptNo() + "," + "总净重:" + bigDecimalNetWeight + unitMap.get(publicGoods.getMaterialUnit()) + "," + "数量:" + productionMaterialReturnDetailList.size() + "," + "交接成功");
                pickingRestHandoverDto.setResultCode("200");
                return pickingRestHandoverDto;
            }
//            }
        }

        //批次
        if (sysDocument.getDocHandoverMethod() == 2) {
            //第一步根据工号查询交接人
            if (pickingRestDbVo.getExecutionOrder() == 1) {
                //根据工号查询交接人
                String userName = pickingRestDbVo.getInputValue();
                AjaxResult byUserName = remoteUserService.getByUserName(userName);
                SysUser userInfo = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);
                //校验员工编号
                if (userInfo.getUserName() == null) {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("交接人输入有误,请核对后输入");
                    return pickingRestHandoverDto;
                }
                //返回交接人
                pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());
                pickingRestHandoverDto.setDocHandoverMethod(sysDocument.getDocHandoverMethod());
                pickingRestHandoverDto.setResultCode("200");
                pickingRestHandoverDto.setMessage("操作成功");
                return pickingRestHandoverDto;
            }
            //第二步输入批次号
            if (pickingRestDbVo.getExecutionOrder() == 2) {
                //通过批次号查询明细数据
                List<ProductionMaterialReturnDetail> productionMaterialReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getBatchNo, pickingRestDbVo.getInputValue()));
                PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, productionMaterialReturnDetailList.get(0).getMaterialCode()));

                if (productionMaterialReturnDetailList.size() > 0) {
                    BigDecimal bigDecimalHand = new BigDecimal(0);
                    for (ProductionMaterialReturnDetail entity : productionMaterialReturnDetailList) {
                        entity.setStatus(3);
                        bigDecimalHand = bigDecimalHand.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
                    }
                    productionMaterialReturnDetailService.updateBatchById(productionMaterialReturnDetailList);
                    //修改仓库表数据
                    List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, pickingRestDbVo.getInputValue()));
                    for (WmsStockInfo info : wmsStockInfoList) {
                        info.setWsiMaterialStatus(2);
                    }
                    wmsStockInfoService.updateBatchById(wmsStockInfoList);
                    //入库数量

                    //交接重量
                    BigDecimal handoverWeight = bigDecimalHand.add(new BigDecimal(String.valueOf(productionMaterialReturn.getHandoverWeight())));

                    //交接数量
                    BigDecimal handoverNum = new BigDecimal(productionMaterialReturnDetailList.size()).add(new BigDecimal(productionMaterialReturn.getHandoverNum()));

                    List<ProductionMaterialReturnDetail> detailListById = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, pickingRestDbVo.getId()));
                    boolean isTrue = true;
                    for (ProductionMaterialReturnDetail entity : detailListById) {
                        if (entity.getStatus() != 3) {
                            isTrue = false;
                            break;
                        }
                    }
                    //如果明细都是已完成，就修改其他入库为已完成
                    if (isTrue) {
                        productionMaterialReturn.setStatus(5);
                    }
                    productionMaterialReturn.setHandoverNum(Integer.parseInt(handoverNum.toString()));
                    productionMaterialReturn.setHandoverWeight(Double.parseDouble(handoverWeight.toString()));
                    String closingBy = productionMaterialReturn.getClosingBy();
                    if (closingBy == null) {
                        productionMaterialReturn.setClosingBy(username);
                    } else {
                        productionMaterialReturn.setClosingBy(closingBy + "," + username);
                    }
                    String closingTime = productionMaterialReturn.getClosingTime();
                    Date date = new Date();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = simpleDateFormat.format(date);
                    if (closingTime == null) {
                        productionMaterialReturn.setClosingTime(closingTime);
                    } else {
                        productionMaterialReturn.setClosingTime(closingTime + "," + format);
                    }
                    updateById(productionMaterialReturn);

                    //设置出参内容
                    pickingRestHandoverDto.setQuantityIdentification(productionMaterialReturn.getPlannedWeight() + "/" + handoverWeight + unitMap.get(publicGoods.getMaterialUnit()));
                    pickingRestHandoverDto.setOutHandoverActual(detailListById.size() + "/" + handoverNum);
                    pickingRestHandoverDto.setMessage("批次号:" + pickingRestDbVo.getInputValue() + "," + "总净重:" + handoverWeight + unitMap.get(publicGoods.getMaterialUnit()) + "," + "数量:" + productionMaterialReturnDetailList.size() + "," + "交接成功");
                    pickingRestHandoverDto.setResultCode("200");
                    return pickingRestHandoverDto;

                } else {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("没有该批次号的数据，请核实后再操作");
                    return pickingRestHandoverDto;
                }
            }
        }
        //单个物料
        if (sysDocument.getDocHandoverMethod() == 1) {
            //第一步根据工号查询交接人
            if (pickingRestDbVo.getExecutionOrder() == 1) {
                //根据工号查询交接人
                String userName = pickingRestDbVo.getInputValue();
                AjaxResult byUserName = remoteUserService.getByUserName(userName);
                SysUser userInfo = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);
                //校验员工编号
                if (userInfo.getUserName() == null) {
                    pickingRestHandoverDto.setResultCode("500");
                    pickingRestHandoverDto.setMessage("交接人输入有误,请核对后输入");
                    return pickingRestHandoverDto;
                }
                //返回交接人
                pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());
                pickingRestHandoverDto.setDocHandoverMethod(sysDocument.getDocHandoverMethod());
                pickingRestHandoverDto.setResultCode("200");
                pickingRestHandoverDto.setMessage("操作成功");
                return pickingRestHandoverDto;
            }
            if (pickingRestDbVo.getExecutionOrder() == 2) {
                PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, pickingRestDbVo.getInputValue()));

                //交接数量
                BigDecimal handoverNum = new BigDecimal(1).add(new BigDecimal(productionMaterialReturn.getHandoverNum()));

                //根据物料条码获取明细信息
                ProductionMaterialReturnDetail productionMaterialReturnDetail = productionMaterialReturnDetailMapper.selectOne(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getMaterialNumber, pickingRestDbVo.getInputValue()));
                //修改该明细状态为已经完成
                productionMaterialReturnDetail.setStatus(3);
                productionMaterialReturnDetailService.updateById(productionMaterialReturnDetail);
                //修改仓库表数据
                WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, productionMaterialReturnDetail.getMaterialNumber()));
                wmsStockInfo.setWsiMaterialStatus(2);
                wmsStockInfoService.updateById(wmsStockInfo);
                //交接重量
                BigDecimal handoverWeight = new BigDecimal(String.valueOf(productionMaterialReturnDetail.getNetWeight())).add(new BigDecimal(String.valueOf(productionMaterialReturn.getHandoverWeight())));

                //判断明细是否都已经交接成功
                List<ProductionMaterialReturnDetail> productionMaterialReturnDetailList = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, pickingRestDbVo.getId()));
                boolean isTrue = true;
                for (ProductionMaterialReturnDetail entity : productionMaterialReturnDetailList) {
                    if (entity.getStatus() != 3) {
                        isTrue = false;
                        break;
                    }
                }
                //如果明细都是已完成，就修改其他入库为已完成
                if (isTrue) {
                    productionMaterialReturn.setStatus(5);
                }
                productionMaterialReturn.setHandoverWeight(Double.parseDouble(handoverWeight.toString()));
                productionMaterialReturn.setHandoverNum(Integer.parseInt(handoverNum.toString()));
                String closingBy = productionMaterialReturn.getClosingBy();
                if (closingBy == null) {
                    productionMaterialReturn.setClosingBy(username);
                } else {
                    productionMaterialReturn.setClosingBy(closingBy + "," + username);
                }
                String closingTime = productionMaterialReturn.getClosingTime();
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String format = simpleDateFormat.format(date);
                if (closingTime == null) {
                    productionMaterialReturn.setClosingTime(closingTime);
                } else {
                    productionMaterialReturn.setClosingTime(closingTime + "," + format);
                }
                updateById(productionMaterialReturn);

                //设置出参内容
                pickingRestHandoverDto.setQuantityIdentification(productionMaterialReturn.getPlannedWeight() + "/" + handoverWeight + unitMap.get(publicGoods.getMaterialUnit()));
                pickingRestHandoverDto.setOutHandoverActual(productionMaterialReturnDetailList.size() + "/" + handoverNum);
                pickingRestHandoverDto.setMessage("物料号码:" + productionMaterialReturnDetail.getMaterialNumber() + "," + "总净重:" + productionMaterialReturnDetail.getNetWeight() + unitMap.get(publicGoods.getMaterialUnit()) + "," + "数量:" + 1 + "," + "交接成功");
                pickingRestHandoverDto.setResultCode("200");
                return pickingRestHandoverDto;
            }
        }
        return pickingRestHandoverDto;
    }

    /**
     * 生产退料品质回传状态(fegin调用)
     *
     * @param updateStatusByQualityVo
     * @return
     */
    @Override
    public boolean updateStatusByQuality(UpdateStatusByQualityVo updateStatusByQualityVo) {
        Long menuId = feignService.getIdByMenuName("生产退料");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        //获取销售退货及对应明细信息
        ProductionMaterialReturn productionMaterialReturn = productionMaterialReturnMapper.selectOne(new QueryWrapper<ProductionMaterialReturn>().lambda().eq(ProductionMaterialReturn::getReceiptNo, updateStatusByQualityVo.getAssociatedNo()));

        List<ProductionMaterialReturnDetail> productionMaterialReturns = productionMaterialReturnDetailMapper.selectList(new QueryWrapper<ProductionMaterialReturnDetail>().lambda().eq(ProductionMaterialReturnDetail::getProductionMaterialReturnId, productionMaterialReturn.getId()));
        //如果单据状态为待检验
        if (productionMaterialReturn.getStatus() == 3) {
            //如果配置了交接
            if (sysDocument.getDocHandoverMark() == 1) {
                productionMaterialReturn.setStatus(4);
                for (ProductionMaterialReturnDetail entity : productionMaterialReturns) {
                    entity.setStatus(2);
                }
            } else {
                for (ProductionMaterialReturnDetail entity : productionMaterialReturns) {
                    entity.setStatus(3);
                }
                productionMaterialReturn.setStatus(5);
            }
        }
        if (productionMaterialReturns.size() > 0) {
            productionMaterialReturnDetailService.updateBatchById(productionMaterialReturns);
        }

        return updateById(productionMaterialReturn);
    }
}
